
//满就送打折促销
package shopping

import (
    "time"
	"strings"
	"strconv"
	"encoding/json"
	"dhfshop/models"
	"dhfshop/models/misc"
	"dhfshop/utils/math"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
)

// 满就送活动表
type MjsActivity struct {
    MjsActivityId int64  `orm:"column(mjs_activity_id);pk;auto" json:"mjs_activity_id" form:"mjs_activity_id"` //活动ID
	PartnerId    int64     `orm:"column(partner_id);index" json:"partner_id" form:"partner_id"`   //商家ID
	StoreId      int64     `orm:"column(store_id);index" json:"store_id" form:"store_id"`         //门店ID
	Name         string    `orm:"column(name);size(32);null" json:"name" form:"name"`       //活动名称
	StartTime    time.Time `orm:"column(start_time);type(datetime);null" json:"-" form:"-"` //活动开始时间
	StartTimeStr string    `orm:"-" json:"start_time" form:"start_time"`                    //输入输出
	EndTime      time.Time `orm:"column(end_time);type(datetime);null" json:"-" form:"-"`   //活动结束时间
	EndTimeStr   string    `orm:"-" json:"end_time" form:"end_time"`                        //输入输出
	TypeId       int       `orm:"column(type_id)" json:"type_id" form:"type_id"`            //1=满件优惠 2=满元优惠
	Piece        int       `orm:"column(piece)" json:"piece" form:"piece"`                           //满几件
	Yuan         float32   `orm:"column(yuan);digits(12);decimals(2)" json:"yuan" form:"yuan"`       //满几元
	Mode         int       `orm:"column(mode)" json:"mode" form:"mode"`                              //优惠方式:1=打折 2=减钱
	Discount     float32   `orm:"column(discount);digits(12);decimals(2)" json:"discount" form:"discount"`   //打几折
    Disprice     float32   `orm:"column(disprice);digits(12);decimals(2)" json:"disprice" form:"disprice"`   //减多少钱
	City         string    `orm:"column(city);type(text);null" json:"city" form:"city"`  
	Ptype        int       `orm:"column(ptype)" json:"ptype" form:"ptype"`                  //活动范围 1=全店, 2=部分商品
	Mianyou      int       `orm:"column(mianyou);default(1)" json:"mianyou" form:"mianyou"` //1=满就送活动 2=满包邮活动
	HType            string `orm:"column(h_type);default(mjs)" json:"h_type" form:"h_type"` //=coupon则对mjs_range表查询
	CouponCount      int64  `orm:"column(coupon_count);null" json:"coupon_count" form:"coupon_count"` //优惠券总张数
	PersonLimitCount int64  `orm:"column(person_limit_count);null" json:"person_limit_count" form:"person_limit_count"` //每人领取张数
	CreatedAt    time.Time `orm:"auto_now_add;column(created_at);type(datetime)" json:"-" form:"-"` 
	CreatedAtStr string    `orm:"-" json:"created_at,omitempty" form:"-"`
    UpdatedAt    time.Time `orm:"auto_now;column(updated_at);type(datetime)" json:"-" form:"-"`         
	UpdatedAtStr string    `orm:"-" json:"updated_at,omitempty" form:"-"`
	MjsActivityItems []*MjsActivityItem `orm:"-" json:"mjs_activity_items" form:"-"`   
}

//参加活动商品表
type MjsActivityItem struct {
    Id         int64     `orm:"column(id);pk;auto" json:"id" form:"id"`
	PartnerId  int64     `orm:"column(partner_id)" json:"partner_id" form:"partner_id"`   //商家ID
    MjsActivityId int64  `orm:"column(mjs_activity_id)" json:"mjs_activity_id" form:"mjs_activity_id"`
	ItemId     int64     `orm:"column(item_id);null" json:"item_id,string" form:"-"`      //商品ID
	ItemIdStr  string    `orm:"-" json:"-" form:"item_id"`                                //输入
}

//定向优惠范围
type MjsRange struct {
    RangeId        int64     `orm:"column(range_id);pk;auto" json:"range_id" form:"range_id"`
	PartnerId      int64     `orm:"column(partner_id)" json:"partner_id" form:"partner_id"`   //商家ID
    StoreId        int64     `orm:"column(store_id)" json:"store_id" form:"store_id"`         //门店ID
	MemberId       int64     `orm:"column(member_id);index" json:"member_id" form:"member_id"`
	SourceMemberId int64     `orm:"column(source_member_id)" json:"source_member_id" form:"source_member_id"`
	MjsActivityId  int64     `orm:"column(mjs_activity_id);index" json:"mjs_activity_id" form:"mjs_activity_id"`
	HasNum         int64     `orm:"column(has_num);default(1)" json:"has_num" form:"has_num"`  //已领优惠券的数量
	UsedNum        int64     `orm:"column(used_num)" json:"used_num" form:"used_num"`          //使用的数量
	CreatedAt      time.Time `orm:"auto_now_add;column(created_at);type(datetime)" json:"-" form:"-"` 
	Id             int64     `orm:"column(id)" json:"id" form:"id"`                            //ID
}
 
func init() {
    orm.RegisterModel(new(MjsActivity),new(MjsActivityItem),new(MjsRange))   
}

func GetMjsActivityById(id int64) (v *MjsActivity, err error) {
	o := models.GetDefaultDB()
	v = &MjsActivity{MjsActivityId: id}
	if err = o.Read(v); err == nil {
		return v, nil
	}
	return nil, err
}

func GetActItemByActId(mjsActivityId int64) (v *MjsActivityItem, err error) {
	o := models.GetDefaultDB()
	v = &MjsActivityItem{MjsActivityId: mjsActivityId}
	if err = o.Read(v, "MjsActivityId"); err == nil {
		return v, nil
	}
	return nil, err
}

func GetActItemsByActId(mjsActivityId int64) (mjsActItems []*MjsActivityItem, err error) {
	o := models.GetDefaultDB()
	mjsActItems = []*MjsActivityItem{}
	qs := o.QueryTable(new(MjsActivityItem)).Filter("mjs_activity_id", mjsActivityId)
	_, err = qs.All(&mjsActItems)
	return
}

func GetTimeValidMjsActs(partnerId, storeId int64, mianyou int) (mjsActs []*MjsActivity, err error) {
	curUtcTime := time.Now().UTC()
	mjsActs = []*MjsActivity{}
	o := models.GetDefaultDB()
	qs := o.QueryTable(new(MjsActivity)).Filter("partner_id",partnerId).Filter("store_id", storeId).Filter("mianyou", mianyou)
	qs = qs.Filter("start_time__lt", curUtcTime)
	qs = qs.Filter("end_time__gt", curUtcTime)
	_, err = qs.All(&mjsActs)
	return
}

func GetMjsRangeById(memberId, mjsActivityId int64) (v *MjsRange, err error) {
	o := models.GetDefaultDB()
	v = &MjsRange{MemberId:memberId, MjsActivityId: mjsActivityId}
	if err = o.Read(v, "MemberId", "MjsActivityId"); err == nil {
		return v, nil
	}
	return nil, err
}

func UpdateMjsRangeUsedNum(memberId, mjsActivityId int64) (err error) {
	o := models.GetDefaultDB()
	v := &MjsRange{MemberId:memberId, MjsActivityId: mjsActivityId}
	m := new(MjsRange)
	if err = o.Read(v,"MemberId","MjsActivityId"); err == nil {
		m.RangeId = v.RangeId
		m.UsedNum = v.UsedNum + 1
		if _, err = o.Update(m, "UsedNum"); err == nil {
			beego.Debug("UpdateMjsRangeUsedNum err", err.Error())
		}
	}
	return
}

/***************************************************************************
淘宝也是这样的：提交订单页面会列出符合条件的优惠活动，若是多个，可以选择一个
********************************************************************************/
type MjsActSimple struct {
    Name       string  `json:"name"`
    Discount   float32 `json:"discount,omitempty"`
	City       string  `json:"-"` 
	CutPostFee int     `json:"cut_post_fee"`  //此活动是否需要减免邮费: 1减免 其他:不减免
	PostFee    float32 `json:"post_fee"`      //订单最初的邮费金额
}

func GetMjsDiscountFee(partnerId,storeId int64,cityId int,postFee float32,orders *ValueOrder) (int64,map[int64]*MjsActSimple,error){
	var curActId int64 = 0
	var maxDiscount float32 = 0.0
	actDiscountMap := make(map[int64]*MjsActSimple)
	mjsActs, err := GetTimeValidMjsActs(partnerId, storeId, 1)
	if err != nil {
	   beego.Debug("GetTimeValidMjsActs err:", err.Error())
	   return  curActId, actDiscountMap, err
	}
	
	if mjsActsJSON, err := json.Marshal(mjsActs); err == nil {
	   beego.Debug("mjsActsJSON:", string(mjsActsJSON))
	}
	
	// 统计订单信息
	itemPaymentMap := make(map[int64]float32)
	itemQuantityMap := make(map[int64]int)
	orderPayment := math.SubPrice(orders.TotalFee, orders.DiscountFee)
	orderQuantity := 0
	for _, orderItem := range orders.Items {
	    if v, ok := itemPaymentMap[orderItem.ItemId]; ok {
		    itemPaymentMap[orderItem.ItemId] = v + orderItem.Payment
		}else{
		    itemPaymentMap[orderItem.ItemId] = orderItem.Payment
		}
		if v, ok := itemQuantityMap[orderItem.ItemId]; ok {
		    itemQuantityMap[orderItem.ItemId] = v + int(orderItem.Quantity)
		}else{
		    itemQuantityMap[orderItem.ItemId] = int(orderItem.Quantity)
		}
	    orderQuantity = orderQuantity + int(orderItem.Quantity)
	}
	//
	for _, act := range mjsActs {
		if act.HType == "coupon" {
		    mjsRange, err := GetMjsRangeById(orders.MemberId, act.MjsActivityId)
			if err != nil {
			   continue
			}
			if mjsRange.HasNum - mjsRange.UsedNum <= 0 {
			   continue
			}
		}
		//全店校验
	    if act.Ptype == 1 {
		   //满件优惠
		   if act.TypeId == 1 {
		      if orderQuantity >= act.Piece {
			     if act.Mode == 1 {  //打折
				     afterDiscountPrice := math.MultiFloat32Price(orderPayment, math.DivTotalFee2(act.Discount, 100))
					 actDiscountMap[act.MjsActivityId] = &MjsActSimple{}
					 actDiscountMap[act.MjsActivityId].Discount = math.SubPrice(orderPayment, afterDiscountPrice)
					 actDiscountMap[act.MjsActivityId].Name = act.Name
					 actDiscountMap[act.MjsActivityId].City = act.City
				 } else {  //减钱
				     actDiscountMap[act.MjsActivityId] = &MjsActSimple{}
					 actDiscountMap[act.MjsActivityId].Discount = act.Disprice
					 actDiscountMap[act.MjsActivityId].Name = act.Name
					 actDiscountMap[act.MjsActivityId].City = act.City
				 }
			  } else {
			     beego.Debug("不满足满件条件:","orderQuantity:",orderQuantity,"act.Piece:", act.Piece)
			  }
		   } else {  //满元优惠
		      if orderPayment >= act.Yuan {
			     if act.Mode == 1 {  //打折
				     afterDiscountPrice := math.MultiFloat32Price(orderPayment, math.DivTotalFee2(act.Discount, 100))
					 actDiscountMap[act.MjsActivityId] = &MjsActSimple{}
					 actDiscountMap[act.MjsActivityId].Discount = math.SubPrice(orderPayment, afterDiscountPrice)
					 actDiscountMap[act.MjsActivityId].Name = act.Name
					 actDiscountMap[act.MjsActivityId].City = act.City
					 
				 } else {  //减钱
				     actDiscountMap[act.MjsActivityId] = &MjsActSimple{}
					 actDiscountMap[act.MjsActivityId].Discount = act.Disprice
					 actDiscountMap[act.MjsActivityId].Name = act.Name
					 actDiscountMap[act.MjsActivityId].City = act.City
				 }
			  }else{
			     beego.Debug("不满足满元条件:","orderPayment:",orderPayment,"act.Yuan:", act.Yuan)
			  }
		   }
		} else {
		    actItems, err := GetActItemsByActId(act.MjsActivityId)
			if err != nil {
		        beego.Debug("GetActItemsByActId err:", err.Error())
				continue
		    }
			partQuantity := 0
			var partPayment float32= 0.0
			for _, actItem := range actItems {
			    if value, ok := itemQuantityMap[actItem.ItemId]; ok {
				    partQuantity = partQuantity + value
			    }
				if value, ok := itemPaymentMap[actItem.ItemId]; ok {
				    partPayment = partPayment + value
			    }
			}
			//满件优惠
			if act.TypeId == 1 {
				if partQuantity >= act.Piece {
					if act.Mode == 1 {  //打折
						afterDiscountPrice := math.MultiFloat32Price(partPayment, math.DivTotalFee2(act.Discount, 100))
						actDiscountMap[act.MjsActivityId] = &MjsActSimple{}
						actDiscountMap[act.MjsActivityId].Discount = math.SubPrice(partPayment, afterDiscountPrice)
						actDiscountMap[act.MjsActivityId].Name = act.Name
						actDiscountMap[act.MjsActivityId].City = act.City
					} else {  //减钱
						actDiscountMap[act.MjsActivityId] = &MjsActSimple{}
						actDiscountMap[act.MjsActivityId].Discount = act.Disprice
						actDiscountMap[act.MjsActivityId].Name = act.Name
						actDiscountMap[act.MjsActivityId].City = act.City
					}	
				}else{
				    beego.Debug("不满足满件条件:","partQuantity:",partQuantity,"act.Piece:", act.Piece)
				}
			} else {  //满元优惠
				if partPayment >= act.Yuan {
				   if act.Mode == 1 {  //打折
						afterDiscountPrice := math.MultiFloat32Price(partPayment, math.DivTotalFee2(act.Discount, 100))
						actDiscountMap[act.MjsActivityId] = &MjsActSimple{}
						actDiscountMap[act.MjsActivityId].Discount = math.SubPrice(partPayment, afterDiscountPrice)
						actDiscountMap[act.MjsActivityId].Name = act.Name
						actDiscountMap[act.MjsActivityId].City = act.City
					} else {  //减钱
						actDiscountMap[act.MjsActivityId] = &MjsActSimple{}
						actDiscountMap[act.MjsActivityId].Discount = act.Disprice
						actDiscountMap[act.MjsActivityId].Name = act.Name
						actDiscountMap[act.MjsActivityId].City = act.City
					}
				}else{
				    beego.Debug("不满足满元条件:","partPayment:",partPayment,"act.Yuan:", act.Yuan)
				}
			}
			/*
			for _, actItem := range actItems {
			    if _, ok := itemQuantityMap[actItem.ItemId]; ok {
					//满件优惠
					if act.TypeId == 1 {
						if itemQuantityMap[actItem.ItemId] >= act.Piece {
							if act.Mode == 1 {  //打折
								afterDiscountPrice := math.MultiFloat32Price(itemPaymentMap[actItem.ItemId], math.DivTotalFee2(act.Discount, 100))
								actDiscountMap[act.MjsActivityId] = &MjsActSimple{}
								actDiscountMap[act.MjsActivityId].Discount = math.SubPrice(itemPaymentMap[actItem.ItemId], afterDiscountPrice)
								actDiscountMap[act.MjsActivityId].Name = act.Name
								actDiscountMap[act.MjsActivityId].City = act.City
							} else {  //减钱
								actDiscountMap[act.MjsActivityId] = &MjsActSimple{}
								actDiscountMap[act.MjsActivityId].Discount = act.Disprice
								actDiscountMap[act.MjsActivityId].Name = act.Name
								actDiscountMap[act.MjsActivityId].City = act.City
							}
						}
					} else {  //满元优惠
						if itemPaymentMap[actItem.ItemId] >= act.Yuan {
							if act.Mode == 1 {  //打折
								afterDiscountPrice := math.MultiFloat32Price(itemPaymentMap[actItem.ItemId], math.DivTotalFee2(act.Discount, 100))
								actDiscountMap[act.MjsActivityId] = &MjsActSimple{}
								actDiscountMap[act.MjsActivityId].Discount = math.SubPrice(itemPaymentMap[actItem.ItemId], afterDiscountPrice)
								actDiscountMap[act.MjsActivityId].Name = act.Name
								actDiscountMap[act.MjsActivityId].City = act.City
							} else {  //减钱
								actDiscountMap[act.MjsActivityId] = &MjsActSimple{}
								actDiscountMap[act.MjsActivityId].Discount = act.Disprice
								actDiscountMap[act.MjsActivityId].Name = act.Name
								actDiscountMap[act.MjsActivityId].City = act.City
							}
						}else{
							beego.Debug("is not itemPaymentMap[actItem.ItemId] >= act.Yuan")
						}
					}	
				}
			}*/	
		}
	}
	for key, value := range actDiscountMap {
	    if value.Discount > maxDiscount {
		    curActId = key
			maxDiscount = value.Discount
		}
		if cutFee, err := isCutPostFee(cityId, value.City); err == nil {
		    value.CutPostFee = cutFee
			value.PostFee = postFee
		}
	}
	if actDiscountMapJSON, err := json.Marshal(actDiscountMap); err == nil {
	   beego.Debug("curActId:",curActId,"actDiscountMapJSON:",string(actDiscountMapJSON))
	}
	return curActId, actDiscountMap, nil
}

func GetMbyPostFee(partnerId,storeId int64,cityId int,postFee float32,orders *ValueOrder) (int64,map[int64]*MjsActSimple,error){
	var curActId int64 = 0
	actDiscountMap := make(map[int64]*MjsActSimple)
	mjsActs, err := GetTimeValidMjsActs(partnerId, storeId, 2)
	if err != nil {
	   return  curActId, actDiscountMap, err
	}
	/*
	if mjsActsJSON, err := json.Marshal(mjsActs); err == nil {
	   beego.Debug("mjsActsJSON:", string(mjsActsJSON))
	}
	*/
	// 统计订单信息
	itemPaymentMap := make(map[int64]float32)
	itemQuantityMap := make(map[int64]int)
	orderPayment := math.SubPrice(orders.TotalFee, orders.DiscountFee)
	orderQuantity := 0
	for _, orderItem := range orders.Items {
		if v, ok := itemPaymentMap[orderItem.ItemId]; ok {
		    itemPaymentMap[orderItem.ItemId] = v + orderItem.Payment
		}else{
		    itemPaymentMap[orderItem.ItemId] = orderItem.Payment
		}
		if v, ok := itemQuantityMap[orderItem.ItemId]; ok {
		    itemQuantityMap[orderItem.ItemId] = v + int(orderItem.Quantity)
		}else{
		    itemQuantityMap[orderItem.ItemId] = int(orderItem.Quantity)
		}
		orderQuantity = orderQuantity + int(orderItem.Quantity)
	}
	//
	for _, act := range mjsActs {
		if act.HType == "coupon" {
		    mjsRange, err := GetMjsRangeById(orders.MemberId, act.MjsActivityId)
			if err != nil {
			   continue
			}
			if mjsRange.HasNum - mjsRange.UsedNum <= 0 {
			   continue
			}
		}
		//全店校验
	    if act.Ptype == 1 {
		   //满件优惠
		   if act.TypeId == 1 {
		        if orderQuantity >= act.Piece {
				    actDiscountMap[act.MjsActivityId] = &MjsActSimple{}
					actDiscountMap[act.MjsActivityId].Name = act.Name
					actDiscountMap[act.MjsActivityId].City = act.City
					if cutFee, err := isCutPostFee(cityId, act.City); err == nil {
						actDiscountMap[act.MjsActivityId].CutPostFee = cutFee
						actDiscountMap[act.MjsActivityId].PostFee = postFee
					}
			    }
		   } else {  //满元优惠
		        if orderPayment >= act.Yuan {
			        actDiscountMap[act.MjsActivityId] = &MjsActSimple{}
					actDiscountMap[act.MjsActivityId].Name = act.Name
					actDiscountMap[act.MjsActivityId].City = act.City
					if cutFee, err := isCutPostFee(cityId, act.City); err == nil {
						actDiscountMap[act.MjsActivityId].CutPostFee = cutFee
						actDiscountMap[act.MjsActivityId].PostFee = postFee
					}
			    }
		   }
		} else {
		    actItems, err := GetActItemsByActId(act.MjsActivityId)
			if err != nil {
		        beego.Debug("GetActItemsByActId err:", err.Error())
				continue
		    }
			partQuantity := 0
			var partPayment float32= 0.0
			for _, actItem := range actItems {
			    if value, ok := itemQuantityMap[actItem.ItemId]; ok {
				    partQuantity = partQuantity + value
			    }
				if value, ok := itemPaymentMap[actItem.ItemId]; ok {
				    partPayment = partPayment + value
			    }
			} 
			//满件优惠
			if act.TypeId == 1 {
				if partQuantity >= act.Piece {
					actDiscountMap[act.MjsActivityId] = &MjsActSimple{}
					actDiscountMap[act.MjsActivityId].Name = act.Name
					actDiscountMap[act.MjsActivityId].City = act.City
					if cutFee, err := isCutPostFee(cityId, act.City); err == nil {
						actDiscountMap[act.MjsActivityId].CutPostFee = cutFee
						actDiscountMap[act.MjsActivityId].PostFee = postFee
					}
				}
			} else {  //满元优惠
				if partPayment >= act.Yuan {
					//beego.Debug("paymap0:",itemPaymentMap[actItem.ItemId],"act.Yuan:",act.Yuan)
					actDiscountMap[act.MjsActivityId] = &MjsActSimple{}
					actDiscountMap[act.MjsActivityId].Name = act.Name
					actDiscountMap[act.MjsActivityId].City = act.City
					if cutFee, err := isCutPostFee(cityId, act.City); err == nil {
						actDiscountMap[act.MjsActivityId].CutPostFee = cutFee
						actDiscountMap[act.MjsActivityId].PostFee = postFee
					}
				}
			}
			/*
			for _, actItem := range actItems {
			    if _, ok := itemQuantityMap[actItem.ItemId]; ok {
				    //满件优惠
					if act.TypeId == 1 {
						if itemQuantityMap[actItem.ItemId] >= act.Piece {
							actDiscountMap[act.MjsActivityId] = &MjsActSimple{}
							actDiscountMap[act.MjsActivityId].Name = act.Name
							actDiscountMap[act.MjsActivityId].City = act.City
							if cutFee, err := isCutPostFee(cityId, act.City); err == nil {
								actDiscountMap[act.MjsActivityId].CutPostFee = cutFee
								actDiscountMap[act.MjsActivityId].PostFee = postFee
							}
						}
					} else {  //满元优惠
						if itemPaymentMap[actItem.ItemId] >= act.Yuan {
							//beego.Debug("paymap0:",itemPaymentMap[actItem.ItemId],"act.Yuan:",act.Yuan)
							actDiscountMap[act.MjsActivityId] = &MjsActSimple{}
							actDiscountMap[act.MjsActivityId].Name = act.Name
							actDiscountMap[act.MjsActivityId].City = act.City
							if cutFee, err := isCutPostFee(cityId, act.City); err == nil {
								actDiscountMap[act.MjsActivityId].CutPostFee = cutFee
								actDiscountMap[act.MjsActivityId].PostFee = postFee
							}
						}else{
						    //beego.Debug("paymap2:",itemPaymentMap[actItem.ItemId],"act.Yuan:",act.Yuan)
						}
					}
			    }
			}*/
				
		}
	}
	for key, _:= range actDiscountMap {
	    curActId = key
		break
	}
	if actDiscountMapJSON, err := json.Marshal(actDiscountMap); err == nil {
	   beego.Debug("curActId:",curActId,"actDiscountMapJSON:",string(actDiscountMapJSON))
	}
	return curActId, actDiscountMap, nil
}


func isCutPostFee(cityId int, curCity string) (int, error) {
	if curCity == "" {
	    return 0, nil
	} else if curCity == "1" {
	    return 1, nil
	} else {
		area, err := misc.GetAreaByAreaId(cityId)
		if err == nil {
			provinceIdStr := strconv.Itoa(area.ParentId)
			if ok := strings.Contains(curCity, provinceIdStr); ok {
				return 1, nil
			}else {
				return 0, nil
			}
		}else{
		   return 0, err
		}
	}
	return 0, nil
}
